package com.ljq.rpc.server.handler;

import com.alibaba.fastjson.JSONObject;
import com.ljq.rpc.common.enums.MsgType;
import com.ljq.rpc.common.pojo.Request;
import com.ljq.rpc.common.pojo.Response;
import com.ljq.rpc.common.protocol.dubboProtocol;
import com.ljq.rpc.server.Listens.RegisterApplicationListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.lang.reflect.Method;

public class NettyServerHandler extends SimpleChannelInboundHandler<dubboProtocol> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("成功与客户端：" + ctx.channel().remoteAddress()+"连接");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("与客户端：" + ctx.channel().remoteAddress()+"失去连接");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, dubboProtocol msg) throws Exception {
        Request request = JSONObject.parseObject(msg.getContent().toString(), Request.class);
        Long request_id = JSONObject.parseObject(msg.getREQUEST_ID().toString(),Long.class);
        Object service = RegisterApplicationListener.getBean(request.getServiceName());
        Method method = service.getClass().getMethod(request.getMethodName(), request.getParametersType());
        Object content = method.invoke(service, getParameters(request));
        dubboProtocol<Response> responseProtocol = new dubboProtocol<Response>(request_id,MsgType.RESPONSE.getTypeID(),new Response(method.getReturnType(),content));
        ctx.writeAndFlush(responseProtocol);
    }

    private Object[] getParameters(Request request){
        Object[] parameters = new Object[request.getParameters().length];
        Object[] paras = request.getParameters();
        Class<?>[] type = request.getParametersType();
        for (int i = 0; i < parameters.length; i++) {
            parameters[i] = JSONObject.parseObject(paras[i].toString(),type[i]);
        }
        return parameters;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
